package pluginUtils;

public class limVector {
	private double x,y,z;
	
	public static final limVector NORTHPOLE=new limVector(0,0,-1); 

	/**
	 * @param x
	 * @param y
	 * @param z
	 */
	public limVector(double x, double y, double z) {
		super();
		this.x = x;
		this.y = y;
		this.z = z;
	}

	/**
	 * @return the x
	 */
	public double getX() {
		return x;
	}

	/**
	 * @param x the x to set
	 */
	public void setX(double x) {
		this.x = x;
	}

	/**
	 * @return the y
	 */
	public double getY() {
		return y;
	}

	/**
	 * @param y the y to set
	 */
	public void setY(double y) {
		this.y = y;
	}

	/**
	 * @return the z
	 */
	public double getZ() {
		return z;
	}

	/**
	 * @param z the z to set
	 */
	public void setZ(double z) {
		this.z = z;
	} 
	
	public limVector vadd(limVector w){
		return new limVector(x+w.x,y+w.y,z+w.z); 
	}
	
	public limVector vsub(limVector w){
		return new limVector(x-w.x,y-w.y,z-w.z); 
	}
	
	public double vabs(){
			return Math.sqrt(x*x+y*y+z*z); 
	}

	public static limVector complexToS2(limComplexe z){
		double r=z.squareNorm(); 
		return new limVector(2*z.getReal()/(1+r),2*z.getIm()/(1+r),(1-r)/(1+r)); 
	}
	
	// TODO : r est modifie, sert dans ps ligne 259...
	public static limPacket circleToS2(limCircle c){
		if(c.getRadius()<0) return lineToS2(c); 
		limComplexe center=c.getCenter(); 
		double s=c.getRadius(); 
		double ac=center.abs();
		double r; 
		if(ac==0){
			limVector v=complexToS2(center); 
			r=2*s/(1+s*s); 
			return new limPacket(v,r); 
		}
		limComplexe cn=limComplexe.mulbyDouble(center,1/ac);
		double w1x=center.getReal()+s*cn.getReal(); 
		double w1y=center.getIm()+s*cn.getIm(); 
		limComplexe w1=limComplexe.createComplexeFromRI(w1x, w1y);
		double w2x=center.getReal()-s*cn.getReal(); 
		double w2y=center.getIm()-s*cn.getIm(); 
		limComplexe w2=limComplexe.createComplexeFromRI(w2x, w2y);
		limVector v1=complexToS2(w1); 
		limVector v2=complexToS2(w2); 
		limVector v=v1.vadd(v2); 
		r=v1.vsub(v2).vabs()/2;
		if(v.vabs()<limConstants.VEPS){
			s=Math.sqrt(v1.x*v1.x+v1.y*v1.y);
			v=new limVector(-v1.x*v1.z/s,-v1.y*v1.z/s,s);
		}
		return new limPacket(v,r); 
	}
	
	
	public static limPacket lineToS2(limCircle c){
		limVector p=complexToS2(c.getCenter());
		if((p.x==0)&&(p.y==0))
			return new limPacket(new limVector(Math.cos(-Math.PI*c.getRadius()),Math.sin(-Math.PI*c.getRadius()),0),1); 
		else{
			limVector v=p.vadd(NORTHPOLE);
			double r=p.vsub(NORTHPOLE).vabs()/2; 
			return new limPacket(v,r);
		}
		
		
		
		
		
		
	}
	
	
}
